subroutine readinp(iunit,lunit,myrank)
  use param
  use global_param
  use output_param
  use data_param
  use mat_param
  use box_param
  use group_param
  use motion_param
  use edit_param
  use table_param
  use run_param
  implicit none

  interface
     function reallocExternType(p,n)
       use derived
       type(ExternalEvent),pointer,dimension(:) :: &
            reallocExternType,p
       integer,intent(in) :: n
     end function reallocExternType

     function reallocObjectGroup(p,n)
       use derived
       type(GroupType),pointer,dimension(:) :: &
            reallocObjectGroup,p
       integer,intent(in) :: n
     end function reallocObjectGroup

     subroutine set_group_type(p,n,str)
       use derived
       type(GroupType),pointer,dimension(:) :: p
       integer,intent(in) :: n
       character :: str*(*)
     end subroutine set_group_type

     function reallocReactGroup(p,n)
       use derived
       type(ReactionRateGroup),pointer,dimension(:) :: &
            reallocReactGroup,p
       integer,intent(in) :: n
     end function reallocReactGroup

     function reallocMotionType(p,n)
       use derived
       type(MotionType),pointer,dimension(:) :: &
            reallocMotionType,p
       integer,intent(in) :: n
     end function reallocMotionType

     function reallocTempProfile(p,n)
       use derived
       type(TemperatureProfile),pointer,dimension(:) :: &
            reallocTempProfile,p
       integer,intent(in) :: n
     end function reallocTempProfile
  end interface

  ! io unit
  integer,intent(in) :: iunit,lunit,myrank

  ! String manipulation
  integer :: len_str,count_line,asci_code,n_word
  character(len=len_linebuf) :: eatline,str_index,null
  character(len=len_wordbuf),dimension(max_n_word) :: eatword

  ! Dummies
  integer :: i,j,n,m

  ! flow control
  logical :: bflag
  
  ! Sort of external event
  integer :: external_event_flag

  null="null"

  ! Write to log
  write(lunit,*)
  write(lunit,'(a)') "Input script"

  ! Loop control
  str_index=null
  bflag=.true.

  count_line=0

  do
     read(iunit,'(a)',end=100,err=101) eatline
     count_line=count_line+1
     len_str=len_trim(eatline)
     write(lunit,'(1x,i3.3," : ",a)') count_line,eatline(1:len_str)
     ! Skip a blank line and reset a command.
     if (len_str.eq.0) then
        bflag=.true.
        str_index=null
        cycle
     end if
     eatline=adjustl(eatline)
     ! Treat the comment line. 
     ! The character "#" denotes the comment line.
     asci_code=ichar(eatline(1:1))
     if (asci_code.eq.ccode) cycle
     read(eatline(1:len_str),*,end=102) &
          (eatword(i),i=1,max_n_word)
102  continue
     n_word=i-1
     if (str_index.eq.null) str_index=eatword(1)

     !<----Treat the command here.---->!
     select case(str_index)
        ! Command : OUTPUT
        case("OUTPUT")
           if (bflag) then
              bflag=.false.
              cycle
           end if
           select case(eatword(1))
              case("spat")
                 print_spatial_dist=.true.
                 psfn=eatword(2)
              case("time")
                 print_time_evol=.true.
                 ptfn=eatword(2)
              case("dpae")
                 print_dpa_evol=.true.
                 pdfn=eatword(2)
              case("rate")
                 print_reaction_rate=.true.
                 n=len_trim(eatword(2))+5
                 write(prfn(1:n),'(a,".r",i3.3)') &
                      trim(eatword(2)),myrank
              case("movi")
                 print_all_position=.true.
                 ppfn=eatword(2)
              case default
                 call show_msg1(lunit,"")
                 call show_msg2(lunit,&
                      "Command : ",&
                      trim(adjustl(str_index)))
                 call show_msg2(lunit,&
                      "Undefined keyword : ",&
                      trim(adjustl(eatword(1))))
                 call abnormal_stop("readinp",&
                      "Unrecognized command is found.")
           end select
        ! Command : DATA
        case("DATA")
           if (bflag) then
              bflag=.false.
              cycle
           end if
           select case(eatword(1))
              case("init")
                 init_exist=.true.
                 infn=eatword(2)
              case("label")
                 label_exist=.true.
                 lafn=eatword(2)
              case("diffusion")
                 diff_exist=.true.
                 dffn=eatword(2)
              case("reaction")
                 react_exist=.true.
                 rtfn=eatword(2)
              case("dissociation")
                 diss_exist=.true.
                 dsfn=eatword(2)
              case("geom")
                 geom_exist=.true.
                 glfn=eatword(2)
              case("sink")
                 sink_exist=.true.
                 gsfn=eatword(2)
              case("source")
                 source_exist=.true.
                 grfn=eatword(2)
              case default
                 call show_msg1(lunit,"")
                 call show_msg2(lunit,&
                      "Command : ",&
                      trim(adjustl(str_index)))
                 call show_msg2(lunit,&
                      "Undefined keyword : ",&
                      trim(adjustl(eatword(1))))
                 call abnormal_stop("readinp",&
                      "Unrecognized command is found.")
           end select
        ! Command : MATERIAL
        case("MATERIAL")
           if (bflag) then
              bflag=.false.
              cycle
           end if
           select case(eatword(1))
              case("lattice")
                 read(eatword(2),*) dist_a0
              case("density")
                 read(eatword(2),*) mat_density
              case("atomic_number")
                 read(eatword(2),*) atomic_no
              case default
                 call show_msg1(lunit,"")
                 call show_msg2(lunit,&
                      "Command : ",&
                      trim(adjustl(str_index)))
                 call show_msg2(lunit,&
                      "Undefined keyword : ",&
                      trim(adjustl(eatword(1))))
                 call abnormal_stop("readinp",&
                      "Unrecognized command is found.")
           end select
        ! Command : BOX_OPTION
        case("BOX_OPTION")
           if (bflag) then
              bflag=.false.
              cycle
           end if
           select case(eatword(1))
              case("x_width")
                 read(eatword(2),*) bwidth(1)
              case("y_width")
                 read(eatword(2),*) bwidth(2)
              case("z_width")
                 read(eatword(2),*) bwidth(3)
              case("n_channel")
                 read(eatword(2),*) channel_n(1)
                 read(eatword(3),*) channel_n(2)
                 read(eatword(4),*) channel_n(3)
              case("cell_width")
                 read(eatword(2),*) cell_width
              case("boundary")
                 read(eatword(2),*) bound(1)
                 read(eatword(3),*) bound(2)
                 read(eatword(4),*) bound(3)
              case default
                 call show_msg1(lunit,"")
                 call show_msg2(lunit,&
                      "Command : ",&
                      trim(adjustl(str_index)))
                 call show_msg2(lunit,&
                      "Undefined keyword : ",&
                      trim(adjustl(eatword(1))))
                 call abnormal_stop("readinp",&
                      "Unrecognized command is found.")
           end select
        ! Command : DEFECT_TYPE
        case("DEFECT_TYPE")
           if (bflag) then
              bflag=.false.
              cycle
           end if
           select case(eatword(1))
              case("n_type")
                 read(eatword(2),*) n_point_type
                 allocate(pdefect(n_point_type))
              case("type")
                 do i=1,n_point_type
                    call set_point_type(lunit,i,eatword(i+1))
                 end do
              case default
           end select
        ! Command : EXTERNAL_EVENT
        case("EXTERNAL_EVENT")
           if (bflag) then
              ! Determine the type of irradiation
              eatword(2)=adjustl(eatword(2))
              asci_code=ichar(eatword(2)(1:1))
              if (asci_code.eq.110.or.asci_code.eq.78) then
                 ! neutron : n,N
                 external_event_flag=1
              else if (asci_code.eq.105.or.asci_code.eq.73) then
                 ! ion : i,I
                 external_event_flag=2
              else if (asci_code.eq.101.or.asci_code.eq.69) then
                 ! electron : e,E
                 external_event_flag=3
              else
                 call abnormal_stop("readinp",&
                      "Unexpected external event type is found.")
              end if
              ! Increase the number of sorts of the external events
              n_ext=n_ext+1
              ! Allocate memory to extern_type
              extern_type=>reallocExternType(extern_type,n_ext)
              ! Save the type of event
              extern_type(n_ext)%event_type=external_event_flag
              bflag=.false.
              cycle
           end if
           select case(eatword(1))
              case("flux")
                 read(eatword(2),*) &
                      extern_type(n_ext)%flux
              case("dose")
                 read(eatword(2),*) &
                      extern_type(n_ext)%dose
              case("rand")
                 read(eatword(2),*) &
                      extern_type(n_ext)%rand
              case("dise")
                 read(eatword(2),*) &
                      extern_type(n_ext)%dise
              case("file")
                 read(eatword(2),*) &
                      extern_type(n_ext)%filename
              case("cdf")
                 read(eatword(2),*) &
                      extern_type(n_ext)%cas_filename
              case("dpa")
                 read(eatword(2),*) &
                      extern_type(n_ext)%dpa_filename
              case("dist")
                 if (n_word.eq.2) then
                    read(eatword(2),*) &
                         extern_type(n_ext)%dist(1)
                    extern_type(n_ext)%dist(2)=&
                         extern_type(n_ext)%dist(1)
                 else if (n_word.eq.3) then
                    read(eatword(2),*) &
                         extern_type(n_ext)%dist(1)
                    read(eatword(3),*) &
                         extern_type(n_ext)%dist(2)
                 else
                    call abnormal_stop("readinp",&
                         "dist in external_event is not &
                         specified properly.")
                 end if
              case("type")
                 if (n_word.lt.2) then
                    call abnormal_stop("readinp",&
                         "type in external_event is not &
                         specified properly.")
                 end if
                 extern_type(n_ext)%n_type=n_word-1
                 allocate(extern_type(n_ext)%source_name(&
                      extern_type(n_ext)%n_type))
                 do i=1,extern_type(n_ext)%n_type
                    extern_type(n_ext)%source_name(i)=&
                         eatword(i+1)
                 end do
              case default
           end select
        ! Command : OUT_UNIT
        case("OUT_UNIT")
           read(eatword(2),*) out_unit
        ! Command : DEFECT_GROUP
        case("DEFECT_GROUP")
           if (bflag) then
              bflag=.false.
              cycle
           end if
           ! Increase the number of groups
           n_object_group=n_object_group+1
           ! Allocate the memory for the group
           object_group=>reallocObjectGroup(object_group,&
                n_object_group)
           call set_group_type(object_group,n_object_group,&
                eatline(1:len_str))
        ! Command : REACTION_RATE
        case("REACTION_RATE")
           if (bflag) then
              n=0
              bflag=.false.
              cycle
           end if
           ! Increase the number of groups 
           ! for recording of the reaction rate
           n=n+1
           n_react_group=n
           ! Allocate the memory for the react_group
           react_group=>reallocReactGroup(react_group,n)
           read(eatword(1),*) m
           ! Determine the type of the reaction rate
           ! 1:object+object (group+grouop)
           ! 2:object dissociation (group)
           ! 3:sink+object (sink+group)
           ! 4:sink dissociation (sink)
           ! 5:free boundary+object (group:escape thru bound)
           if (m.ge.1.or.m.le.5) then
              react_group(n)%react_type=m
           else
              call show_msg2(lunit,"Command : ",&
                   trim(adjustl(str_index)))
              call abnormal_stop("readinp",&
                   "Unexpected reaction rate is found.")
           end if
           ! Common for all reaction types
           read(eatword(2),*) m
           react_group(n)%target1=m
           ! Not applied in the case of reaction_type=2
           if (react_group(n)%react_type.eq.1.or.&
                react_group(n)%react_type.eq.3) then
              read(eatword(3),*) m
              react_group(n)%target2=m
           else
              ! 2,4,5
              react_group(n)%target2=0
           end if
        ! Command : OBJECT_MOTION
        case("OBJECT_MOTION")
           if (bflag) then
              n=0
              bflag=.false.
              cycle
           end if
           select case(eatword(1))
              case("default")
                 select case(eatword(2))
                    case("0d")
                       default_motion=0
                    case("1d")
                       default_motion=1
                    case("2d")
                       default_motion=2
                    case("3d")
                       default_motion=3
                    case("f3d")
                       default_motion=4
                    case default
                       call show_msg2(lunit,&
                            "Command: ",&
                            trim(adjustl(eatword(1)))//" "&
                            //trim(adjustl(eatword(2))))
                       call abnormal_stop("readinp",&
                            "Unrecognized command is found.")
                 end select
              case("0d")
                 n=n+1
                 n_motion=n
                 mtype=>reallocMotionType(mtype,n)
                 mtype(n)%motion_type=0
                 read(eatword(2),*) mtype(n)%group_no
              case("1d")
                 n=n+1
                 n_motion=n
                 mtype=>reallocMotionType(mtype,n)
                 mtype(n)%motion_type=1
                 read(eatword(2),*) mtype(n)%group_no
              case("2d")
                 n=n+1
                 n_motion=n
                 mtype=>reallocMotionType(mtype,n)
                 mtype(n)%motion_type=2
                 read(eatword(2),*) mtype(n)%group_no
              case("3d")
                 n=n+1
                 n_motion=n
                 mtype=>reallocMotionType(mtype,n)
                 mtype(n)%motion_type=3
                 read(eatword(2),*) mtype(n)%group_no
              case("f3d")
                 n=n+1
                 n_motion=n
                 mtype=>reallocMotionType(mtype,n)
                 mtype(n)%motion_type=4
                 read(eatword(2),*) mtype(n)%group_no
              case default
                 call show_msg2(lunit,&
                      "Command: ",&
                      trim(adjustl(eatword(1)))//" "&
                      //trim(adjustl(eatword(2))))
                 call abnormal_stop("readinp",&
                      "Unrecognized command is found.")
           end select
           if (default_motion.lt.0) &
                call abnormal_stop("readinp",&
                "The mode for default motion is not specified.")
        ! Command : OUTPUT_EDIT
        case("OUTPUT_EDIT")
           if (bflag) then
              bflag=.false.
              cycle
           end if
           select case(eatword(1))
              case("time")
                 select case(eatword(2))
                    case("log")
                       time_scale=1
                    case("lin")
                       time_scale=2
                    case default
                       call show_msg1(lunit,"")
                       call show_msg2(lunit,&
                            "Command : ",&
                            trim(adjustl(str_index)))
                       call show_msg2(lunit,&
                            "Undefined keyword : ",&
                            trim(adjustl(eatword(2))))
                       call abnormal_stop("readinp",&
                            "Unrecognized command is found.")
                 end select
                 read(eatword(3),*) start_time
                 read(eatword(4),*) time_width
              case("iter")
                 time_scale=3
                 read(eatword(2),*) iter_width
              case default
                 call show_msg1(lunit,"")
                 call show_msg2(lunit,&
                      "Command : ",&
                      trim(adjustl(str_index)))
                 call show_msg2(lunit,&
                      "Undefined keyword : ",&
                      trim(adjustl(eatword(1))))
                 call abnormal_stop("readinp",&
                      "Unrecognized command is found.")
           end select
        ! Command : OPTION
        case("OPTION")
           if (bflag) then
              bflag=.false.
              cycle
           end if
           select case(eatword(1))
              case("n_object")
                 read(eatword(2),*) default_alloc_sim_obj
                 read(eatword(3),*) add_alloc_sim_obj
              case("n_event")
                 read(eatword(2),*) default_alloc_event_table
              case("seed")
                 read(eatword(2),*) user_seed
              case default
           end select
        ! Command : RUN
        case("RUN")
           if (bflag) then
              n=0
              bflag=.false.
              cycle
           end if
           ! temp xx until loop_option xx external_event_option
           if (eatword(1).ne."temp") &
                call abnormal_stop("readinp",&
                "Keyword [temp] must be required.")
           n=n+1
           n_temp_profile=n
           temp_profile=>reallocTempProfile(temp_profile,n)
           ! temperature
           read(eatword(2),*) temp_profile(n)%temp
           ! loop_option(1/2/3)
           select case(eatword(4))
              case("time")
                 temp_profile(n)%loop_condition=1
                 read(eatword(5),*) &
                      temp_profile(n)%stop_condition
              case("loop")
                 temp_profile(n)%loop_condition=2
                 read(eatword(5),*) m
                 temp_profile(n)%stop_condition=real(m)
              case("dpa")
                 temp_profile(n)%loop_condition=3
                 read(eatword(5),*) &
                      temp_profile(n)%stop_condition
              case default
                 call show_msg1(lunit,"")
                 call show_msg2(lunit,&
                      "Command : ",&
                      trim(adjustl(str_index)))
                 call show_msg2(lunit,&
                      "Undefined keyword : ",&
                      trim(adjustl(eatword(4))))
                 call abnormal_stop("readinp",&
                      "Unrecognized command is found.")
           end select
           ! external_event_flag (0:off/1:on)
           read(eatword(6),*) &
                temp_profile(n)%external_event_flag

           ! Check whether the flag is set correctly.
           if (temp_profile(n)%external_event_flag.lt.0) &
                call abnormal_stop("readinp",&
                "The external event flag might not be defined.")
        ! Command : Exceptional case
        case default
           call show_msg2(lunit,"Command : ",&
                trim(adjustl(str_index)))
           call abnormal_stop("readinp",&
                "Undefined commands.")
     end select
  end do

101 continue
  call abnormal_stop("readinp",&
       "Error occur during reading input file.")
100 continue

  return

end subroutine readinp
